﻿

namespace LS.Nc6.Core;
/// <summary>
/// 请求日志拦截
/// </summary>
public class RequestActionFilter : IAsyncActionFilter
{
    private readonly IEventPublisher _eventPublisher;

    public RequestActionFilter(IEventPublisher eventPublisher)
    {
        _eventPublisher = eventPublisher;
    }

    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        var httpContext = context.HttpContext;
        var httpRequest = httpContext.Request;

        var sw = new Stopwatch();
        sw.Start();
        var actionContext = await next();
        sw.Stop();

        // 判断是否请求成功（没有异常就是请求成功）
        var isRequestSucceed = actionContext.Exception == null;
        var headers = httpRequest.Headers;
        var clientInfo = headers.ContainsKey("User-Agent") ? Parser.GetDefault().Parse(headers["User-Agent"]) : null;
        var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        var isWriteLog = false;
        var ip = Util.HttpNewUtil.Ip;
        //判断是否需有禁用操作日志属性
        foreach (var metadata in actionDescriptor.EndpointMetadata)
        {
            if (metadata.GetType() == typeof(OpLogAttribute))
            {
                isWriteLog = true;
                break;
            }
        }
        //请求异常时记录日志
        if (!isRequestSucceed || App.GetOptions<SystemSettingsOptions>().IsGlobalRequestLog)
        {
            isWriteLog = true;
        }
        if (isWriteLog)
        {
            await _eventPublisher.PublishAsync(new ChannelEventSource("Create:OpLog", new SysOperateLogEntity
            {
                CreateBy = httpContext.User?.FindFirst(ClaimConst.CLAINM_USERID).Value,
                OperateState = isRequestSucceed ? 1 :0,
                OperateIp =ip,
                ActionName = actionDescriptor?.ActionName,
                ControllerName = context.Controller.ToString(),
                Parameter = JSON.Serialize(context.ActionArguments.Count < 1 ? "" : context.ActionArguments),
                CreateDate = DateTime.Now,
                OperateMsg = actionContext.Result?.GetType() == typeof(JsonResult) ? JSON.Serialize(actionContext.Result) : "",
                ConsumedTime = sw.ElapsedMilliseconds
            }));
        }
    }
}
